package compress

import (
	"archive/tar"
	"compress/gzip"
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func Gzip(path string) error {
	t1 := time.Now()
	defer func() {
		fmt.Println("Gzip 执行时间: ", time.Since(t1))
	}()
	// 检查输入路径是否有效
	fi, err := os.Stat(path)
	if err != nil {
		return fmt.Errorf("Unable to tar files - %v", err.Error())
	}
	// 当前仅支持文件夹压缩
	if !fi.IsDir() {
		return errors.New("Unable to tar files - only support dir")
	}
	// 创建输出文件
	fw, err := os.Create(filepath.Base(path) + ".tar.gz")
	if err != nil {
		return fmt.Errorf("Unable to tar files - %v", err.Error())
	}
	defer fw.Close()
	// 创建 tar gip Writer
	gzw := gzip.NewWriter(fw)
	defer gzw.Close()
	tw := tar.NewWriter(gzw)
	defer tw.Close()
	// walk path
	return filepath.Walk(path, func(file string, fi os.FileInfo, err error) error {
		// return on any error
		if err != nil {
			return err
		}
		// 跳过根目录
		if file == path {
			return nil
		}
		// create a new dir/file header
		header, err := tar.FileInfoHeader(fi, fi.Name())
		if err != nil {
			return err
		}
		// update the name to correctly reflect the desired destination when untaring
		header.Name = strings.TrimPrefix(strings.Replace(file, path, filepath.Base(path)+string(filepath.Separator), -1), string(filepath.Separator))
		fmt.Println("a", header.Name)
		// write the header
		if err := tw.WriteHeader(header); err != nil {
			return err
		}
		// return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update)
		if !fi.Mode().IsRegular() {
			return nil
		}
		// open files for taring
		f, err := os.Open(file)
		defer f.Close()
		if err != nil {
			return err
		}
		// copy file data into tar writer
		if _, err := io.Copy(tw, f); err != nil {
			return err
		}
		return nil
	})
}
